//
//  BLSwiftPlayer.swift
//  player_demo
//
//  Created by cgw on 2024/7/4.
//

import UIKit
import CoreMedia
import AVFoundation


/*
 基于AVPlayer的视频播放器
 优势：资源占用较小
 缺点：仅支持部分格式
 */
class BLSwiftPlayer: UIViewController, PlayerDelegate, PlayerPlaybackDelegate {
    
    let player = Player()
    let controlView = BLPlayerControlView()
    
    var url: URL?
    var videoTitle: String?
    var playBeginTime: TimeInterval = 0
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        self.controlView.embedIn(self.view)
        
        self.setupPlayer()
        
        guard let url = url else {
            return
        }
        
        
        self.controlView.setupVideoTitle(self.videoTitle)
        self.play(url: url)
    }
    
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        
        //解决内存泄露问题
        self.controlView.delegate = nil
        self.controlView.removeFromSuperview()
        
        self.player.stop()
        self.player.playerDelegate = nil
        self.player.playbackDelegate = nil
        self.player.view.removeFromSuperview()
        self.player.removeFromParent()
    }
    
    static func play(url: URL, title: String? = nil, from: UIViewController) {
        let vc = BLSwiftPlayer()
        vc.url = url
        vc.videoTitle = title
        from.present(vc, animated: true)
    }
    
    func play(url: URL) {
        
        self.player.url = url
        if self.playBeginTime <= 0 {
            self.player.playFromBeginning()
        }else{
            let scale = (self.player.currentTime.timescale)
            let ct = CMTime.init(seconds: Double(self.playBeginTime), preferredTimescale: 1000)
            //设置开始播放时间
            self.player._seekTimeRequested = ct
            self.player.playFromCurrentTime()
        }
    }
    
    func setupPlayer() {
        self.view.backgroundColor = .black
        self.controlView.delegate = self
        
        self.player.playerDelegate = self
        self.player.playbackDelegate = self
        self.player.autoplay = false

        self.addChild(self.player)
        self.player.view.embedIn(self.view)
        self.player.didMove(toParent: self)
        
        self.view.bringSubviewToFront(self.controlView)
    }
}

extension BLSwiftPlayer {
    // MARK: - player delegate
    func playerReady(_ player: Player) {
        
    }
    
    func playerPlaybackStateDidChange(_ player: Player) {
        let state = self.player.playbackState
        self.controlView.setIsPlaying(state == .playing)
    }
    
    func playerBufferingStateDidChange(_ player: Player) {
        
    }
    
    func playerBufferTimeDidChange(_ bufferTime: Double) {
        
    }
    
    func player(_ player: Player, didFailWithError error: Error?) {
        print("播放错误：\(error)")
    }
    
    // MARK: - playback delegate
    func playerCurrentTimeDidChange(_ player: Player) {
        if self.controlView.isDraggingSlider {
            return 
        }
//            print("time:\(player.currentTimeInterval)/\(player.maximumDuration)")
        self.controlView.setPlayTime(player.currentTimeInterval, totalTime: player.maximumDuration)
    }
    
    func playerPlaybackWillStartFromBeginning(_ player: Player) {
        
    }
    
    func playerPlaybackDidEnd(_ player: Player) {
        
    }
    
    func playerPlaybackWillLoop(_ player: Player) {
        
    }
    
    func playerPlaybackDidLoop(_ player: Player) {
        
    }
}


extension BLSwiftPlayer: BLPlayerControlViewDelegate{
    func playerControlView(_ controlView: BLPlayerControlView, handlePlayBtn: UIButton) {
        let state = self.player.playbackState
        if state == .playing{
            self.player.pause()
        }else{
            self.player.playFromCurrentTime()
            ///重新播放时，恢复一下速率
            DispatchQueue.main.asyncAfter(deadline: .now()+0.1) {
                self.player.rate = self.controlView.rateBtn.rate
            }
        }
    }
    
    func playerControlView(_ controlView: BLPlayerControlView, handleBackBtn: UIButton) {
        if let c = self.parent as? BLPlayer {
            c.dismiss(animated: true)
        }else{
            self.dismiss(animated: true)
        }
    }
    
    func playerControlView(_ controlView: BLPlayerControlView, handleRateBtn: UIButton) {
        
        self.controlView.showSelectRateView(self.player.rate) { newRate in
            self.player.rate = Float(newRate)
        }
    }
    
    func playerControlView(_ controlView: BLPlayerControlView, handleFullScreenBtn: UIButton) {
        
    }
    
    func playerControlView(_ controlView: BLPlayerControlView, handleSliderStart: UISlider) {
        
    }
    
    func playerControlView(_ controlView: BLPlayerControlView, handleSliderEnd: UISlider) {
        
        let scale = Int64(self.player.currentTime.timescale)
        let ct = player.maximumDuration*TimeInterval(handleSliderEnd.value)*TimeInterval(scale)

        let currentTime = CMTimeMake(value: Int64(ct), timescale: Int32(scale))

        print("开始定位时间：\(currentTime.value)")
        self.player.seekToTime(to: currentTime, toleranceBefore: CMTime.zero, toleranceAfter: CMTime.zero) { fini in
            print("定位时间完成")
            self.player.rate = self.controlView.rateBtn.rate
            self.controlView.isDraggingSlider = false
            self.playerControlView(controlView, handleSliderOutEnd: handleSliderEnd)
        }
    }
    
    func playerControlView(_ controlView: BLPlayerControlView, handleSliderOutEnd: UISlider) {
        
    }
    
    func playerControlView(_ controlView: BLPlayerControlView, handleSliderValueChange: UISlider) {
//        let ct = player.maximumDuration*TimeInterval(handleSliderValueChange.value)
//        self.controlView.setPlayTime(ct, totalTime: player.maximumDuration)
    }
    
    func playerControlView(_ controlView: BLPlayerControlView, getImageFromDuration duration: TimeInterval, complete: @escaping (UIImage) -> Void) {
        DispatchQueue.global().async {
            if let img = self.player.getVideoCurrentImage(second: duration) {
                DispatchQueue.main.async {
                    complete(img)
                }
            }
        }
    }
    
    func playerControlView(_ controlView: BLPlayerControlView, updatePlayRate rate: Double){
        self.player.rate = Float(rate)
    }
}


extension Player{
    /// 获取视频的关键图片
    ///
    /// - Returns: 第几秒的图片
    func getVideoCurrentImage(second:TimeInterval) -> UIImage? {
        guard let avAsset = self.asset else {
            return nil
        }
        
        let generator = AVAssetImageGenerator(asset: avAsset)
        generator.appliesPreferredTrackTransform = true
        let time = CMTimeMake(value: Int64(second)*1000, timescale: 1000) //CMTimeMakeWithSeconds(second, preferredTimescale: 1000)
        var actualTime:CMTime = CMTimeMake(value: 0,timescale: 0)
        do {
            let imageRef:CGImage = try generator.copyCGImage(at: time, actualTime: &actualTime)
            let currentImage = UIImage(cgImage: imageRef)
            
            return currentImage
        } catch  {
            
        }
        return nil
    }
}
